package com.gking.processHarvest.service.Project;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gking.processHarvest.common.BaseContext;
import com.gking.processHarvest.common.CustomException;
import com.gking.processHarvest.common.Res;
import com.gking.processHarvest.entity.Harvest;
import com.gking.processHarvest.entity.Module;
import com.gking.processHarvest.entity.Project;
import com.gking.processHarvest.entity.ShareProject;
import com.gking.processHarvest.mapper.ProjectMapper;
import com.gking.processHarvest.service.Harvest.HarvestService;
import com.gking.processHarvest.service.Module.ModuleService;
import com.gking.processHarvest.service.ShareProject.ShareProjectService;
import com.gking.processHarvest.utils.CheckStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Slf4j
@Service
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) //三级缓存解决bean循环注入问题
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements ProjectService {

    @Autowired
    private ModuleService moduleService;

    @Autowired
    private HarvestService harvestService;

    @Autowired
    private ShareProjectService shareProjectService;


    /**
     * 创建项目
     *
     * @param title       项目标题
     * @param description 项目描述
     * @return s
     */
    @Override
    public Res<String> createProject(String title, String description) {
        if (title == null || description == null) return Res.error("请将参数补充完整！");

        Project project = new Project();

        project.setTitle(title);
        project.setDescription(description);

        this.save(project);
        return Res.success("创建项目成功！");
    }


    /**
     * 删除项目
     *
     * @param projectId 项目 id
     * @return s
     */
    @Override
    @Transactional
    public Res<String> deleteProject(String projectId) {
        if (projectId == null || projectId.equals("")) return Res.error("请将参数补充完整");

        //查询项目是否存在且未删除
        CheckStatus<Project> checkStatus = new CheckStatus<>();
        LambdaQueryWrapper<Project> lambdaQueryWrapper = checkStatus.checkIsDelete(
                projectId, Project::getId,
                Project::getMasterId, Project::getIsDelete);
        if (this.getOne(lambdaQueryWrapper) == null) return Res.error("删除项目失败！");

        //存在则删除
        LambdaUpdateWrapper<Project> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(Project::getId, projectId);
        queryWrapper.eq(Project::getMasterId, BaseContext.getCurrentId());
        queryWrapper.set(Project::getIsDelete, 1);
        queryWrapper.set(Project::getDeleteTime, LocalDateTime.now());
        this.update(queryWrapper);

        try {
            //查询项目下的模块，并进行删除
            CheckStatus<Module> checkStatus1 = new CheckStatus<>();
            LambdaQueryWrapper<Module> wrapper1 = checkStatus1.checkIsDelete(
                    projectId, Module::getProjectId,
                    Module::getMasterId, Module::getIsDelete);
            moduleService.list(wrapper1).forEach(item -> moduleService.delete(item.getId()));

            //查询项目下的收获，并进行删除
            CheckStatus<Harvest> checkStatus2 = new CheckStatus<>();
            LambdaQueryWrapper<Harvest> wrapper2 = checkStatus2.checkIsDelete(
                    projectId, Harvest::getProjectId,
                    Harvest::getMasterId, Harvest::getIsDelete);
            harvestService.list(wrapper2).forEach(item -> harvestService.delete(item.getId()));

            //查询分享给好友的项目信息，并进行删除
            LambdaQueryWrapper<ShareProject> wrapper3 = new LambdaQueryWrapper<>();
            wrapper3.eq(ShareProject::getProjectId, projectId);
            wrapper3.eq(ShareProject::getMasterId, BaseContext.getCurrentId());
            shareProjectService.list(wrapper3).forEach(item -> shareProjectService.delete(item.getFriendId(), projectId));

        } catch (Exception e) {
            throw new CustomException("删除项目成功，删除项目下的子模块时出现未知错误！");
        }

        return Res.success("删除项目成功！");
    }


    /**
     * 修改项目信息
     *
     * @param projectId   项目id
     * @param title       项目 标题
     * @param description 项目描述
     * @return s
     */
    @Override
    @Transactional
    public Res<String> updateInfo(String projectId, String title, String description) {

        //查看项目是否存在且未删除
        CheckStatus<Project> checkStatus = new CheckStatus<>();
        LambdaQueryWrapper<Project> lambdaQueryWrapper = checkStatus.checkIsDelete(
                projectId, Project::getId,
                Project::getMasterId, Project::getIsDelete);
        if (this.getOne(lambdaQueryWrapper) == null) return Res.error("修改项目信息失败！");

        //项目没有删除，则修改信息
        LambdaUpdateWrapper<Project> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Project::getId, projectId);
        updateWrapper.eq(Project::getMasterId, BaseContext.getCurrentId());
        updateWrapper.set(Project::getTitle, title);
        updateWrapper.set(Project::getDescription, description);
        this.update(updateWrapper);

        try {
            //修改分享给好友项目里的相关信息
            LambdaUpdateWrapper<ShareProject> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(ShareProject::getProjectId, projectId);
            wrapper.eq(ShareProject::getMasterId, BaseContext.getCurrentId());
            wrapper.set(ShareProject::getProjectTitle, title);
            shareProjectService.update(wrapper);
        } catch (Exception e) {
            throw new CustomException("修改项目信息成功，但是修改分享给好友的项目信息失败！");
        }

        return Res.success("修改项目信息成功！");
    }


    /**
     * 分页查询项目
     *
     * @param page     分页页码
     * @param pageSize 分页大小
     * @return s
     */
    @Override
    public Res<Page> getProjectList(Integer page, Integer pageSize) {
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Project::getMasterId, BaseContext.getCurrentId());
        queryWrapper.eq(Project::getIsDelete, 0);
        queryWrapper.orderByDesc(Project::getCreateTime);

        Page<Project> pageInfo = new Page<>(page, pageSize);
        Page<Project> pageData = this.page(pageInfo, queryWrapper);
        return  Res.success("分页获取项目列表成功！", pageData);
    }

}
